package com.cupk.utils;

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

public class ImgUtil {
    static{
        // 得保证先执行该语句，用于加载库，才能调用其他操作库的语句，
        // 设置本地库路径 这句话很重要，如果没有，下面这个函数将报错：Mat img = Imgcodecs.imread(path);
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("DetectServiceImpl Loading Lib: opencv");
    }

    public static Mat bufferedImageToMat(BufferedImage bi) {
        Mat mat = new Mat(bi.getHeight(), bi.getWidth(), CvType.CV_8UC3);
        int[] data = new int[bi.getWidth() * bi.getHeight() * 3];
        bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), data, 0, bi.getWidth());
        byte[] matData = new byte[data.length];
        for (int i = 0; i < data.length; i++) {
            matData[i] = (byte) data[i];
        }
        mat.put(0, 0, matData);
        return mat;
    }

    public static Mat readImageFromUrl(String url) throws IOException {
        URL imageUrl = new URL(url);
        BufferedImage bufferedImage = ImageIO.read(imageUrl);
        return bufferedImageToMat(bufferedImage);
    }

    public static double LoadingCalculateSimilarity(String imageUrl1, String imageUrl2) {
        double similarity = 0.0;
        try {
            Mat img1 = readImageFromUrl(imageUrl1);
            Mat img2 = readImageFromUrl(imageUrl2);
            similarity = calculateSimilarity(img1, img2);
            System.out.println("Similarity: " + similarity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return similarity;
    }

    private static double calculateSimilarity(Mat image1, Mat image2) {
        Mat image1Gray = new Mat();
        Mat image2Gray = new Mat();
        Imgproc.cvtColor(image1, image1Gray, Imgproc.COLOR_BGR2GRAY);
        Imgproc.cvtColor(image2, image2Gray, Imgproc.COLOR_BGR2GRAY);
        // 调整图片为同一大小
        Size size = new Size(Math.min(image1Gray.width(), image2Gray.width()), Math.min(image1Gray.height(), image2Gray.height()));
        Imgproc.resize(image1Gray, image1Gray, size);
        Imgproc.resize(image2Gray, image2Gray, size);

        MatOfFloat ssimMat = new MatOfFloat();
        Imgproc.matchTemplate(image1Gray, image2Gray, ssimMat, Imgproc.TM_CCOEFF_NORMED);
        Scalar ssimScalar = Core.mean(ssimMat);
        return ssimScalar.val[0];
    }
}
